package com.springboot.demo.utils;

import cn.hutool.core.util.HexUtil;
import com.springboot.demo.exception.BusinessException;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author wubc683
 * @desc
 * @date 2021-07-30 17:23
 */

public class CommonUtils {
    private static String passwordPattern = "^[a-zA-Z0-9_]{6,16}$";
    // 该正则表达式可以匹配所有的数字 包括负数
    private static Pattern isNumberPattern = Pattern.compile("-?[0-9]+(\\.[0-9]+)?");
    private static Pattern isDigitPattern = Pattern.compile("[0-9]+");

    /**
     * 校验手机号
     *
     * @param phone
     * @return: boolean
     */
    public static boolean checkPhone(String phone) {
        if (phone == null || phone.length() != 11) {
            return false;
        } else {
            /**
             * 移动号段正则表达式
             */
            String pat1 = "^((13[4-9])|(147)|(15[0-2,7-9])|(178)|(18[2-4,7-8]))\\d{8}|(1705)\\d{7}$";
            /**
             * 联通号段正则表达式
             */
            String pat2 = "^((13[0-2])|(145)|(15[5-6])|(176)|(18[5,6]))\\d{8}|(1709)\\d{7}$";
            /**
             * 电信号段正则表达式
             */
            String pat3 = "^((133)|(153)|(177)|(18[0,1,9])|(149))\\d{8}$";
            /**
             * 虚拟运营商正则表达式
             */
            String pat4 = "^((170))\\d{8}|(1718)|(1719)\\d{7}$";

            return isPatMatch(pat1, phone) || isPatMatch(pat2, phone) || isPatMatch(pat3, phone) || isPatMatch(pat4, phone);
        }
    }

    private static Boolean isPatMatch(String pat, String phone) {
        Pattern pattern = Pattern.compile(pat);
        Matcher match4 = pattern.matcher(phone);
        return match4.matches();
    }

    /**
     * 校验密码
     *
     * @param password
     * @return: java.lang.Boolean
     */
    public static Boolean checkPassword(String password) {
        Pattern p = Pattern.compile(passwordPattern);
        Matcher m = p.matcher(password);
        return m.matches();
    }

    public static Boolean isDigit(String str) {
        return isDigitPattern.matcher(str).matches();
    }

    // 分享时修改名字，不能超过31字符，加后缀_1,_2...
    public static String getDifferentName(String name, List<String> names) {
        String diffName = null;
        // 太长的名字，截短一点
        if (name.length() >= 24) {
            name = name.substring(0, 24);
        }
        for (int i = 1; i < 9999999; i++) {
            diffName = name + "_" + i;
            if (!names.contains(diffName)) {
                return diffName;
            }
        }
        // 连续分享场景超过9999999个
        throw new BusinessException(ResponseResult.NAME_DUPLICATE_TOO_MUCH);
    }

    /**
     * 集合元素判重
     *
     * @param datas
     * @return: boolean
     */
    public static boolean isRepeatInCollection(Collection<?> datas) {
        // 为空则认为不含重复元素
        if (datas == null) {
            return false;
        }
        Set<?> noRepeatSet = new HashSet<>(datas);
        return !(datas.size() == noRepeatSet.size());
    }

//    /**
//     * 校验值是否合法
//     * @param s
//     * @return: void
//     */
//    public static void checkValueValidity(String s) {
//        Float aFloat = null;
//        try {
//            aFloat = Float.valueOf(s);
//        } catch (NumberFormatException e) {
//            throw new BusinessException(ResponseResult.VALUE_ILLEGAL);
//        }
//        if(Float.isInfinite(aFloat)){
//            throw new BusinessException(ResponseResult.VALUE_TOO_LARGE);
//        }
//    }

    /**
     * 判断字符串是否能转成数字
     *
     * @param str
     * @return: boolean
     */
    public static boolean isNumeric(String str) {
        String bigStr;
        try {
            bigStr = new BigDecimal(str).toString();
        } catch (Exception e) {
            return false;//异常 说明包含非数字。
        }
        Matcher isNum = isNumberPattern.matcher(bigStr); // matcher是全匹配
        if (!isNum.matches()) {
            return false;
        }
        return true;
    }

    /**
     * 获取所有省份
     *
     * @param
     * @return: java.util.Map<java.lang.String, java.lang.Object>
     */
    public static Map<Integer, Object> getAllProvince() {
        Map<Integer, Object> map = new HashMap<>();
        map.put(0, "北京市");
        map.put(1, "广东省");
        map.put(2, "山东省");
        map.put(3, "江苏省");
        map.put(4, "河南省");
        map.put(5, "上海市");
        map.put(6, "河北省");
        map.put(7, "浙江省");
        map.put(8, "香港特别行政区");
        map.put(9, "陕西省");
        map.put(10, "湖南省");
        map.put(11, "重庆市");
        map.put(12, "福建省");
        map.put(13, "天津市");
        map.put(14, "云南省");
        map.put(15, "四川省");
        map.put(16, "广西壮族自治区");
        map.put(17, "安徽省");
        map.put(18, "海南省");
        map.put(19, "江西省");
        map.put(20, "湖北省");
        map.put(21, "山西省");
        map.put(22, "辽宁省");
        map.put(23, "台湾省");
        map.put(24, "黑龙江");
        map.put(25, "内蒙古自治区");
        map.put(26, "澳门特别行政区");
        map.put(27, "贵州省");
        map.put(28, "甘肃省");
        map.put(29, "青海省");
        map.put(30, "新疆维吾尔自治区");
        map.put(31, "西藏");
        map.put(32, "吉林省");
        map.put(33, "宁夏回族自治区");
        map.put(34, "海外");
        return map;
    }

    public static Map<Integer, String> getCities(int provinceNum) {
        String[] beijing = {"朝阳区", "海淀区", "通州区", "房山区", "丰台区", "昌平区", "大兴区", "顺义区", "西城区", "延庆县", "石景山区", "宣武区", "怀柔区", "崇文区", "密云县", "东城区", "平谷区", "门头沟区"};
        String[] guangdong = {"东莞市", "广州市", "中山市", "深圳市", "惠州市", "江门市", "珠海市", "汕头市", "佛山市", "湛江市", "河源市", "肇庆市", "清远市", "潮州市", "韶关市", "揭阳市", "阳江市", "梅州市", "云浮市", "茂名市", "汕尾市"};
        String[] shangdong = {"济南市", "青岛市", "临沂市", "济宁市", "菏泽市", "烟台市", "淄博市", "泰安市", "潍坊市", "日照市", "威海市", "滨州市", "东营市", "聊城市", "德州市", "莱芜市", "枣庄市"};
        String[] jiangsu = {"苏州市", "徐州市", "盐城市", "无锡市", "南京市", "南通市", "连云港市", "常州市", "镇江市", "扬州市", "淮安市", "泰州市", "宿迁市"};
        String[] henan = {"郑州市", "南阳市", "新乡市", "安阳市", "洛阳市", "信阳市", "平顶山市", "周口市", "商丘市", "开封市", "焦作市", "驻马店市", "濮阳市", "三门峡市", "漯河市", "许昌市", "鹤壁市", "济源市"};
        String[] shanghai = {"松江区", "宝山区", "金山区", "嘉定区", "南汇区", "青浦区", "浦东新区", "奉贤区", "徐汇区", "静安区", "闵行区", "黄浦区", "杨浦区", "虹口区", "普陀区", "闸北区", "长宁区", "崇明县", "卢湾区"};
        String[] hebei = {"石家庄市", "唐山市", "保定市", "邯郸市", "邢台市", "河北区", "沧州市", "秦皇岛市", "张家口市", "衡水市", "廊坊市", "承德市"};
        String[] zhejiang = {"温州市", "宁波市", "杭州市", "台州市", "嘉兴市", "金华市", "湖州市", "绍兴市", "舟山市", "丽水市", "衢州市"};
        String[] hongkong = {"香港市"};
        String[] shangxi = {"西安市", "咸阳市", "宝鸡市", "汉中市", "渭南市", "安康市", "榆林市", "商洛市", "延安市", "铜川市"};
        String[] hunan = {"长沙市", "邵阳市", "常德市", "衡阳市", "株洲市", "湘潭市", "永州市", "岳阳市", "怀化市", "郴州市", "娄底市", "益阳市", "张家界市", "湘西州"};
        String[] chongqing = {"江北区", "渝北区", "沙坪坝区", "九龙坡区", "万州区", "永川市", "南岸区", "酉阳县", "北碚区", "涪陵区", "秀山县", "巴南区", "渝中区", "石柱县", "忠县", "合川市", "大渡口区", "开县", "长寿区", "荣昌县", "云阳县", "梁平县", "潼南县", "江津市", "彭水县", "綦江县", "璧山县", "黔江区", "大足县", "巫山县", "巫溪县", "垫江县", "丰都县", "武隆县", "万盛区", "铜梁县", "南川市", "奉节县", "双桥区", "城口县"};
        String[] fujiang = {"漳州市", "厦门市", "泉州市", "福州市", "莆田市", "宁德市", "三明市", "南平市", "龙岩市"};
        String[] tianjin = {"和平区", "北辰区", "河北区", "河西区", "西青区", "津南区", "东丽区", "武清区", "宝坻区", "红桥区", "大港区", "汉沽区", "静海县", "塘沽区", "宁河县", "蓟县", "南开区", "河东区"};
        String[] yunnan = {"昆明市", "红河州", "大理州", "文山州", "德宏州", "曲靖市", "昭通市", "楚雄州", "保山市", "玉溪市", "丽江地区", "临沧地区", "思茅地区", "西双版纳州", "怒江州", "迪庆州"};
        String[] sichuang = {"成都市", "绵阳市", "广元市", "达州市", "南充市", "德阳市", "广安市", "阿坝州", "巴中市", "遂宁市", "内江市", "凉山州", "攀枝花市", "乐山市", "自贡市", "泸州市", "雅安市", "宜宾市", "资阳市", "眉山市", "甘孜州"};
        String[] guangxi = {"贵港市", "玉林市", "北海市", "南宁市", "柳州市", "桂林市", "梧州市", "钦州市", "来宾市", "河池市", "百色市", "贺州市", "崇左市", "防城港市"};
        String[] anhui = {"芜湖市", "合肥市", "六安市", "宿州市", "阜阳市", "安庆市", "马鞍山市", "蚌埠市", "淮北市", "淮南市", "宣城市", "黄山市", "铜陵市", "亳州市", "池州市", "巢湖市", "滁州市"};
        String[] hainan = {"三亚市", "海口市", "琼海市", "文昌市", "东方市", "昌江县", "陵水县", "乐东县", "保亭县", "五指山市", "澄迈县", "万宁市", "儋州市", "临高县", "白沙县", "定安县", "琼中县", "屯昌县"};
        String[] jiangxi = {"南昌市", "赣州市", "上饶市", "吉安市", "九江市", "新余市", "抚州市", "宜春市", "景德镇市", "萍乡市", "鹰潭市"};
        String[] hubei = {"武汉市", "宜昌市", "襄樊市", "荆州市", "恩施州", "黄冈市", "孝感市", "十堰市", "咸宁市", "黄石市", "仙桃市", "天门市", "随州市", "荆门市", "潜江市", "鄂州市", "神农架林区"};
        String[] shanxi = {"太原市", "大同市", "运城市", "长治市", "晋城市", "忻州市", "临汾市", "吕梁市", "晋中市", "阳泉市", "朔州市"};
        String[] liaoling = {"大连市", "沈阳市", "丹东市", "辽阳市", "葫芦岛市", "锦州市", "朝阳市", "营口市", "鞍山市", "抚顺市", "阜新市", "盘锦市", "本溪市", "铁岭市"};
        String[] taiwang = {"台北市", "高雄市", "台中市", "新竹市", "基隆市", "台南市", "嘉义市"};
        String[] heilongjiang = {"齐齐哈尔市", "哈尔滨市", "大庆市", "佳木斯市", "双鸭山市", "牡丹江市", "鸡西市", "黑河市", "绥化市", "鹤岗市", "伊春市", "大兴安岭地区", "七台河市"};
        String[] neimenggu = {"赤峰市", "包头市", "通辽市", "呼和浩特市", "鄂尔多斯市", "乌海市", "呼伦贝尔市", "兴安盟", "巴彦淖尔盟", "乌兰察布盟", "锡林郭勒盟", "阿拉善盟"};
        String[] aomen = {"澳门特别行政区卫星地图"};
        String[] guizhou = {"贵阳市", "黔东南州", "黔南州", "遵义市", "黔西南州", "毕节地区", "铜仁地区", "安顺市", "六盘水市"};
        String[] gansu = {"兰州市", "天水市", "庆阳市", "武威市", "酒泉市", "张掖市", "陇南地区", "白银市", "定西地区", "平凉市", "嘉峪关市", "临夏回族自治州", "金昌市", "甘南州"};
        String[] qinghai = {"西宁市", "海西州", "海东地区", "海北州", "果洛州", "玉树州", "黄南藏族自治州"};
        String[] xinjiang = {"乌鲁木齐市", "伊犁州", "昌吉州", "石河子市", "哈密地区", "阿克苏地区", "巴音郭楞州", "喀什地区", "塔城地区", "克拉玛依市", "和田地区", "阿勒泰州", "吐鲁番地区", "阿拉尔市", "博尔塔拉州", "五家渠市", "克孜勒苏州", "图木舒克市"};
        String[] xizang = {"拉萨市", "山南地区", "林芝地区", "日喀则地区", "阿里地区", "昌都地区", "那曲地区"};
        String[] jining = {"吉林市", "长春市", "白山市", "延边州", "白城市", "松原市", "辽源市", "通化市", "四平市"};
        String[] ningxia = {"银川市", "吴忠市", "中卫市", "石嘴山市", "固原市"};
        List<String[]> strings = new ArrayList<>();
        strings.add(beijing);
        strings.add(guangdong);
        strings.add(shangdong);
        strings.add(jiangsu);
        strings.add(henan);
        strings.add(shanghai);
        strings.add(hebei);
        strings.add(zhejiang);
        strings.add(hongkong);
        strings.add(shangxi);
        strings.add(hunan);
        strings.add(chongqing);
        strings.add(fujiang);
        strings.add(tianjin);
        strings.add(yunnan);
        strings.add(sichuang);
        strings.add(guangxi);
        strings.add(anhui);
        strings.add(hainan);
        strings.add(jiangxi);
        strings.add(hubei);
        strings.add(shanxi);
        strings.add(liaoling);
        strings.add(taiwang);
        strings.add(heilongjiang);
        strings.add(neimenggu);
        strings.add(aomen);
        strings.add(guizhou);
        strings.add(gansu);
        strings.add(qinghai);
        strings.add(xinjiang);
        strings.add(xizang);
        strings.add(jining);
        strings.add(ningxia);

        Map<Integer, String> cities = new HashMap<>();
        int prefix = 0;
        if (provinceNum == -1) {
            for (int i = 0; i < strings.size(); i++) {
                String[] arr = strings.get(i);
                for (int j = 0; j < arr.length; j++) {
                    cities.put(prefix + j, arr[j]);
                }
                prefix += 100;
            }
        } else if (provinceNum >= 0 && provinceNum <= 33) {
            String[] strings1 = strings.get(provinceNum);
            prefix = 100 * provinceNum;
            for (int i = 0; i < strings1.length; i++) {
                cities.put(prefix + i, strings1[i]);
            }
        }
        return cities;
    }


    /**
     * 校验sort格式是否正确
     *
     * @param sort
     * @param fields
     * @return: void
     */
    public static void checkSortValidity(String sort, List<String> fields) {
        if (!StringUtils.isEmpty(sort)) {
            String[] s = sort.split("\\s+");
            if (s.length == 2 && ("desc".equals(s[1]) || "asc".equals(s[1]))) {
                if (!fields.contains(s[0])) {
                    throw new BusinessException(ResponseResult.SORT_FIELD_FORMAT_ERROR);
                }
            } else {
                throw new BusinessException(ResponseResult.SORT_FIELD_FORMAT_ERROR);
            }
        }
    }


    /**
     * 转换10进制数字形式的mac地址为16位
     *
     * @param macAddr
     * @return: java.lang.String
     */
    public static String macNum2str(Long macAddr) {
        int count = 12;
        StringBuilder builder = new StringBuilder();
        while (count > 0) {
            long l = macAddr % 16;
            if (l >= 0 && l <= 9) {
                builder.insert(0, l);
            } else if (l >= 10) {
                builder.insert(0, (char) ('A' + l - 10));
            }
            if (count != 1 && count % 2 == 1) {
                builder.insert(0, '-');
            }
            macAddr /= 16;
            count--;
        }
        return builder.toString();
    }

    /**
     * 转换16进制字符形式的mac地址为10进制数字
     *
     * @param macAddr
     * @return: java.lang.Long
     */
    public static Long macStr2num(String macAddr) {
        macAddr = macAddr.replace("-", "");
        return HexUtil.hexToLong(macAddr);
    }

    /**
     * 判断字符串是不是double型
     *
     * @param str
     * @return
     */
    public static boolean isFloat(String str) {
        Pattern pattern = Pattern.compile("[0-9]{1,39}(.[0-9]+)?");
        Matcher isNum = pattern.matcher(str);
        if (!isNum.matches()) {
            return false;
        }
        return true;
    }

    /**
     * 截断可转换为float类型的字符串，如果有小数点，只保留6位
     *
     * @param str
     * @return: java.lang.String
     */
    public static String truncateFloatString(String str) {
        String res = str;
        int i = str.indexOf('.');
        if (i != -1) {
            res = str.substring(0, i + 7);
        }
        return res;
    }

    /**
     * 去除小数后面多余的0
     *
     * @param num
     * @return: java.lang.String
     */
    public static String removeTailZero(String num) {
        int i = num.length() - 1;
        for (; i >= 0; i--) {
            if (num.charAt(i) == '.') {
                break;
            } else if (num.charAt(i) != '0') {
                i++;
                break;
            }
        }
        return num.substring(0, i);
    }

}